home *** CD-ROM | disk | FTP | other *** search
- /*
- * COPYRIGHT 1987 CORNELL UNIVERSITY; All Rights Reserved
- * Please see detailed copyrights and disclaimers in "notices.h"
- */
-
- /***************************************************************************
- * This is the 3270 datastream command processor. It is passed a pointer *
- * to a string containing one 3270 command and associated orders and/or *
- * data and the length of the string to process. *
- * written by Peter Hoyt, Cornell Computer Services
- * and bloody well extensively modified by kevin eric saunders!
- ***************************************************************************/
-
- #include <em.h>
- #include <3270.h>
-
- #ifdef USEMACTCP
- #include "mactcp.h"
- #endif
-
-
- /* the possible emulator states ... */
-
- #define CMNORM 0
- #define CMCONT 1
- #define CMWRITE 2
- #define CMWRITE1 3
- #define CMEAT 4
- #define CMEAT1 5
- #define CMSBA 6
- #define CMSBA1 7
- #define CMRA 8
- #define CMRA1 9
- #define CMRA2 10
- #define CMEUA 11
- #define CMEUA1 12
- #define CMSF 13
-
-
- char commandmap[256]; /* map of write orders to avoid switch overhead */
-
- cmd(ptr, length)
- register unsigned char *ptr;
- register int length;
- {
- register unsigned char * curptr;
- register unsigned char * mapend = smap_end;
- register unsigned char thechar; /* current data/command byte */
- register short haddata; /* the last byte processed was data */
- unsigned char * attp;
- unsigned char achar;
- short acount;
- short cnt;
- struct token * tkptr;
-
- if (length == 0)
- return(0);
-
- if (cmdstate) {
- /* we were in the middle of handling a 3270 command string;
- resume where we left off. curptr & emdp->savcount states must
- be maintained */
- curptr = emdp->savcurptr;
- haddata = emdp->savdata;
-
- if (cmdstate == CMCONT) {
- /* we just needed to restore state before proceeding */
- thechar = *ptr++;
- --length;
- }
- else if (cmdstate == CMWRITE1)
- /* predominant case */
- goto CMDWRITE1;
-
- switch (cmdstate) {
- case CMWRITE:
- goto CMDWRITE;
- case CMSF:
- goto CMDSF;
- case CMSBA:
- goto CMDSBA;
- case CMSBA1:
- goto CMDSBA1;
- case CMRA:
- goto CMDRA;
- case CMRA1:
- goto CMDRA1;
- case CMRA2:
- goto CMDRA2;
- case CMEAT:
- goto CMDEAT;
- case CMEAT1:
- goto CMDEAT1;
- case CMEUA:
- goto CMDEUA;
- case CMEUA1:
- goto CMDEUA1;
- }
- }
- else {
- cmdstate = CMCONT;
- thechar = *ptr++;
- --length;
- }
-
- switch (thechar) {
- case EW:
- /* erase / write command */
- case EWA: {
- /* erase / write alternate */
- /* reset the screen buffer & reposition cursor
- if most recent action (or cmd) not a CLEAR */
- if (!(emdp->event_reg & CLEAR_KEY)) {
- modflg = SCRALLMOD;
- mem_clear(scr_map, emdp->screensize, (char) IBMNULL);
- cursor_ptr = scr_map;
- current_attr = NULL;
- newibmcursor();
- }
- /* these guys fall into normal write */
- /* we may spend a lot of time in here now */
- }
- case W: {
- /* write command */
- /* TODO lookahead crap */
- if (length == 4 && *(ptr + 1) == 0x11)
- /* check for special case of using a lone SBA */
- emdp->scr_flag = 1;
- else {
- /* to establish screen buffer ptr for a read command that
- is to follow immediately */
- emdp->scr_flag = 0;
- emdp->scr_org = scr_map;
- }
- /* ignore command if no WCC ? */
- /* kevin TODO should not ignore EAU! 3-2 3270 guide ? */
-
- CMDWRITE:
- if (--length < 0) {
- cmdstate = CMWRITE;
- goto end_write;
- }
- thechar = *ptr++;
-
- /* next char has WCC command stuff in it */
- if (thechar & SNDALRM)
- emdp->event_reg |= SOUND_ALARM;
- /* process WCC */
- if (thechar & KYBDRST)
- emdp->event_reg |= KYBD_RESTORE;
- /* execute later */
- if ((thechar & RMDT) && current_attr != NULL) {
- /* reset MDT */
- attp = current_attr;
- *attp &= ~MDT;
- while ((attp = look_attr(attp, FWD)) != current_attr)
- *attp &= ~MDT;
- }
-
- curptr = cursor_ptr;
- /* default */
- haddata = FALSE;
- /* last char. processed not data */
- firstp = NULL;
-
- length = ft_check(ptr, length);
- /* TODO lookahead crap */
- /* check for file transfer */
- while (TRUE) {
- /* process orders & data */
- CMDWRITE1:
- if (--length < 0) {
- cmdstate = CMWRITE1;
- goto end_write;
- }
- thechar = *ptr++;
-
- if (!commandmap[thechar]) {
- /* normal data for screen display */
- if (!firstp)
- firstp = curptr;
- thechar = ebctoasc[thechar];
- *curptr++ = thechar;
- if (curptr >= mapend) {
- set_mod(firstp, curptr - firstp);
- curptr = scr_map;
- firstp = NULL;
- }
- haddata = TRUE;
- if (emdp->matchinput) {
- /* we're trying to match input characters */
- if (matchtoken(thechar))
- resumetokens(emdp);
- }
- continue;
- /* for program tab */
- }
- else {
- switch (thechar) {
- /* check for orders */
- /* not all orders are supported */
- case 0x2c: /* modify field */
- case 0x29: /* start field extended */
- case 0x28: /* set attribute */
- {
- if (thechar != 0x28) {
- CMDEAT:
- if (--length < 0) {
- cmdstate = CMEAT;
- goto end_write;
- }
- thechar = *ptr++;
- }
- else
- thechar = 1;
- for (emdp->savcount = (thechar * 2); emdp->savcount--; ) {
- /* eat unwanted type/value pairs */
- CMDEAT1:
- if (--length < 0) {
- cmdstate = CMEAT1;
- goto end_write;
- }
- thechar = *ptr++;
- }
- haddata = FALSE;
- break;
- }
- case 0x08: {
- /* graphics escape is ignored */
- haddata = FALSE;
- break;
- }
- case SF: {
- /* start field */
- unsigned char * nfield;
-
- if (firstp) {
- /* do set mod for touched range */
-
- set_mod(firstp, curptr - firstp);
- firstp = NULL;
- }
- CMDSF:
- if (--length < 0) {
- cmdstate = CMSF;
- goto end_write;
- }
- thechar = *ptr++;
-
- if (thechar & HOSTPROT)
- thechar |= PROT;
- else
- thechar &= ~PROT;
-
- thechar &= 0x1F;
- /* see if the new field needs to have modflg set on its range */
- if (modflg < SCRALLMOD) {
- nfield = look_attr(curptr, BACK);
- if ((*nfield & emdp->realattr)
- != (thechar & emdp->realattr)) {
-
- nfield = look_attr(curptr, FWD);
- if (nfield > curptr) {
- acount = nfield - curptr;
- }
- else {
- acount = nfield - scr_map + mapend - curptr;
- }
- set_mod(curptr, acount);
- }
- }
- *curptr++ = thechar; /* mask out irrelevant part */
- if (curptr >= mapend)
- curptr = scr_map;
-
- haddata = FALSE;
- break;
- }
- case SBA: {
- /* set buffer address */
- if (firstp) {
- /* do set mod for touched range */
- set_mod(firstp, curptr - firstp);
- firstp = NULL;
- }
- CMDSBA:
- if (--length < 0) {
- cmdstate = CMSBA;
- goto end_write;
- }
- thechar = *ptr++;
-
- emdp->savcount = ((short) (thechar & 0x3f)) * 64;
- CMDSBA1:
- if (--length < 0) {
- cmdstate = CMSBA1;
- goto end_write;
- }
- thechar = *ptr++;
-
- emdp->savcount += (short) (thechar & 0x3f);
- curptr = scr_map + emdp->savcount;
- while (curptr >= mapend)
- curptr -= emdp->screensize;
- if (emdp->scr_flag) {
- emdp->scr_flag = 0; /* set special pointer */
- emdp->scr_org = curptr; /* this one time */
- }
- haddata = FALSE;
- break;
- }
- case IC: {
- /* insert cursor */
- cursor_ptr = curptr;
- newibmcursor();
- haddata = FALSE;
- break;
- }
- case RA: {
- /* repeat to address */
- if (firstp) {
- /* do set mod for touched range */
- set_mod(firstp, curptr - firstp);
- firstp = NULL;
- }
- /* first figure address itself */
- CMDRA:
- if (--length < 0) {
- cmdstate = CMRA;
- goto end_write;
- }
- thechar = *ptr++;
- emdp->savcount = ((short) (thechar & 0x3f)) * 64;
- CMDRA1:
- /* then figure distance to it */
- if (--length < 0) {
- cmdstate = CMRA1;
- goto end_write;
- }
- thechar = *ptr++;
- emdp->savcount += (short) (thechar & 0x3f);
-
- /* get character to repeat */
- CMDRA2:
- if (--length < 0) {
- cmdstate = CMRA2;
- goto end_write;
- }
- thechar = *ptr++;
-
- /* are we ahead of or behind the cursor ? */
- if (emdp->savcount > emdp->screensize)
- /* keep it inside the buffer! */
- emdp->savcount = emdp->screensize;
-
- /* translate emdp->savcount from address to counter */
- if (scr_map + emdp->savcount > curptr)
- emdp->savcount -= curptr - scr_map;
- else
- emdp->savcount += mapend - curptr;
-
- if (curptr + emdp->savcount > mapend) {
- /* will we wrap? */
- cnt = (mapend - curptr);
- mem_clear(curptr, cnt, ebctoasc[thechar]);
- set_mod(curptr, cnt);
-
- mem_clear(scr_map, emdp->savcount - cnt, ebctoasc[thechar]);
- set_mod(scr_map, emdp->savcount - cnt);
- }
- else {
- mem_clear(curptr, emdp->savcount, ebctoasc[thechar]);
- set_mod(curptr, emdp->savcount);
- }
- curptr += emdp->savcount;
- /* fix the buffer pointer */
- while (curptr >= mapend)
- /* was if */
- curptr -= emdp->screensize;
- haddata = FALSE;
- break;
- }
- case EUA: {
- /* erase unprotected to address */
- if (firstp) {
- /* do set mod for touched range */
- set_mod(firstp, curptr - firstp);
- firstp = NULL;
- }
- /* ugh.. not thoroughly tested */
- CMDEUA:
- if (--length < 0) {
- cmdstate = CMEUA;
- goto end_write;
- }
- thechar = *ptr++;
- emdp->savcount = ((short) (thechar & 0x3f)) * 64;
- CMDEUA1:
- if (--length < 0) {
- cmdstate = CMEUA1;
- goto end_write;
- }
- thechar = *ptr++;
- emdp->savcount += (short) (thechar & 0x3f); /* calc. dist. to addr. */
- if (emdp->savcount > emdp->screensize)
- /* keep it inside the buffer! */
- emdp->savcount = emdp->screensize;
-
- if (scr_map + emdp->savcount > curptr)
- emdp->savcount -= (curptr - scr_map);
- else
- emdp->savcount += (mapend - curptr);
- /* must be formatted buffer */
- if ((attp = look_attr(curptr, BACK)) != NULL) {
- set_mod(curptr, emdp->savcount);
- while (emdp->savcount-- > 0) {
- /* not attr & unprotected */
-
- if (*curptr >= ATTR && !(*attp & PROT))
- *curptr = IBMNULL;
- if (++curptr == mapend)
- curptr = scr_map;
- if (*curptr < ATTR)
- attp = curptr; /* new field */
- }
- }
- haddata = FALSE;
- break;
- }
- case PT: {
- /* program tab */
- if (firstp) {
- /* do set mod for touched range */
- set_mod(firstp, curptr - firstp);
- firstp = NULL;
- }
- if (haddata == FALSE) {
- curptr = first_unp(curptr);
- /* haddata remains false */
- }
- else {
- while (curptr != mapend && *curptr >= ATTR) {
- *curptr = IBMNULL;
- set_mod(curptr++, 1);
- /* EFFICIENCY */
- }
- if (curptr >= mapend) {
- /* frought with special cases */
- curptr = scr_map;
- /* haddata remains true */
- }
- else {
- /* NORMAL CASE? haddata && middle of screen */
- /* HOYT: probably dosen't work & never meant to */
- curptr = first_unp(curptr);
- haddata = FALSE;
- }
- }
- break;
- }
- }
- }
- /* end of switch on next order or data */
- /* we have processed another order or data byte */
- }
- /* end while loop (write command) */
-
- end_write:
- /* branch here if orphan order */
-
- if (firstp != NULL) {
- /* do set mod for touched range */
- set_mod(firstp, curptr - firstp);
- firstp = NULL;
- }
- emdp->savcurptr = curptr;
- emdp->savdata = haddata;
- if (emdp->event_reg & TFTP_ON) {
- /* we've gone into file transfer mode, end of cmd */
- cmdcomplete();
- }
-
- return(0);
- }
-
- /* other 3270 commands follow */
-
- case 0x02: {
- /* read buffer */
- read_buf();
- break;
- }
- case 0x06: {
- /* read modified unsolicited by action key */
- /* most read modifies are handled by the telnet
- server on the host since we pass the results
- of one every time we send an action key */
- read_mod();
- emdp->scr_org = scr_map;
- break;
- }
- case 0x0f: {
- /* erase all unprotected */
- if (current_attr) {
- /* do only if formatted buffer */
- eau();
- /* manual is unclear on this */
- emdp->event_reg |= KYBD_RESTORE;
- emdp->event_reg |= SCREEN_REFRESH;
- }
- emdp->scr_org = scr_map;
- break;
- }
- default: {
- /* something unknown */
- if (!emdp->emdisable)
- beep();
- break;
- }
- }
-
- return();
- }
-
-
- /* a 3270 command is complete, indicated by receipt of IAC EOR */
-
- cmdcomplete()
- {
- cmdstate = CMNORM;
- if (emdp->event_reg & SOUND_ALARM) {
- /* deal with postponed actions */
- if (emdp->ayt_sent == 0 && !emdp->emdisable)
- /* don't beep if this is just a response to an Are You There */
- beep();
- emdp->ayt_sent = 0;
- emdp->event_reg &= ~SOUND_ALARM;
- }
- if (emdp->event_reg & KYBD_RESTORE) {
- emdp->event_reg &= ~KYBD_RESTORE;
- if (emdp->event_reg & KYBD_LOCK) {
- clrkbdlock();
- emdp->event_reg &= ~KYBD_LOCK;
- }
- if (emdp->event_reg & SYS_LOCK) {
- clrsyslock();
- emdp->event_reg &= ~SYS_LOCK;
- }
- emdp->aid_key = AID_RESET;
- }
- emdp->event_reg |= SCREEN_EVENT;
- emdp->event_reg &= ~CLEAR_KEY;
- /* most recent action no longer CLEAR */
-
- if (*cursor_ptr < ATTR) /* reposition current attr pointer */
- current_attr = cursor_ptr;
- else
- current_attr = look_attr(cursor_ptr, BACK);
- }
-
-
- /* send the current buffer to the host
- Note if using only MacTCP, TC_PUT macro can be used */
-
- read_buf()
- {
- register unsigned char * curptr;
- register unsigned char * mapend = smap_end;
- register unsigned char achar;
- register short acount;
-
- (*emdp->putchar)(emdp->aid_key);
- /* return AID & cursor address */
- acount = addr_12 (cursor_ptr - scr_map);
- (*emdp->putchar)(acount >> 8);
- (*emdp->putchar)(acount & 0xff);
-
- for (curptr = emdp->scr_org; curptr < mapend; ) {
- if ((achar = *curptr++) >= ATTR) {
- /* send data */
- (*emdp->putchar)(asctoebc[achar]);
- }
- else {
- /* if new field (because of attr) */
- (*emdp->putchar)(0x1d);
- /* send SF order + attr */
- if (achar & PROT) {
- /* put the protected bit in the right place */
- achar &= ~PROT;
- achar |= HOSTPROT;
- }
- achar = achar & 0x3f;
- achar |= 0x40;
- if ((achar & 0x0f) <= 9) {
- if ((achar & 0x30) == 0x30
- || (achar & 0x0f) > 2
- || achar == 0x41
- || achar == 0x51
- )
- achar |= 0x80;
- }
- (*emdp->putchar)(achar);
- }
- }
- /* don't forget telnet command */
- (*emdp->putchar)(0xff);
- (*emdp->putchar)(0xef);
- (*emdp->putflush)();
-
- emdp->scr_org = scr_map;
- }
-
-
- /* Read modify logic used by both command processor & keyboard routine.
- ** In a real 3270 the host always issues a read modify and the terminal
- ** sends the most recent AID, cursor addr, & any fields with MDT set. In
- ** our telnet application, we perform the read modified and send the data
- ** when the user presses ENTER or a PF key, and the telnet server uses the
- ** data when the host application issues the read modified. In addition the
- ** local PC application must provide for the host issuing a read modified
- ** at any time. Ergo rather than duplicate code we made this subroutine.
- */
-
- read_mod()
- {
- register unsigned char * ptr;
- register unsigned char * mapend = smap_end;
- register unsigned char * nullp;
- unsigned char * endp;
- unsigned char * nextattp;
-
- register unsigned short thechar;
- register short fieldcount;
- short count;
- unsigned char aid = emdp->aid_key;
-
- (*emdp->putchar)(aid);
- /* send AID & cursor addr */
- if (! ((aid == RPA1)
- || (aid == RPA2)
- || (aid == RPA3)
- || (aid == RCLEAR) )) {
-
- /* PA keys and CLEAR produce only AID, no data */
- count = addr_12(cursor_ptr - scr_map);
- (*emdp->putchar)(count >> 8);
- (*emdp->putchar)(count & 0xff);
- if (emdp->scr_org == scr_map)
- /* so as not to miss a field that */
- /* starts at upper left */
- ptr = look_attr(scr_map + emdp->screensize - 1, FWD);
- else
- /* special case SBA + nothing */
- ptr = look_attr(emdp->scr_org, FWD);
-
- if (ptr == NULL) {
- /* unformatted buffer */
- for (ptr = emdp->scr_org; ptr < mapend; ) {
- if ((thechar = *ptr++) != IBMNULL) {
- /* translate character */
- (*emdp->putchar)(asctoebc[thechar]);
- }
- }
- }
- else {
- endp = ptr;
- do {
- if (*ptr & MDT) {
- /* if MDT for this field, field modified */
- nullp = nextattp = look_attr(ptr, FWD);
- if (ptr < nextattp)
- /* "normal" case */
- fieldcount = (nullp - ptr);
- else
- /* we've wrapped */
- fieldcount = (nullp - scr_map) + (smap_end - ptr);
- /* note that fieldcount is 1 high for predecrement */
-
- if (++ptr == mapend)
- ptr = scr_map;
- (*emdp->putchar)(0x11);
- /* SBA order */
- count = addr_12(ptr - scr_map);
- (*emdp->putchar)(count >> 8);
- (*emdp->putchar)(count & 0xff);
- if (fieldcount) {
- /* adjust end so consecutive nulls won't be sent */
- if (nullp <= scr_map)
- nullp += emdp->screensize;
-
- while (--fieldcount && *--nullp == IBMNULL ) {
- if (nullp <= scr_map)
- nullp += emdp->screensize;
- }
- if (fieldcount)
- /* we had some non-nulls & maybe some imbedded nulls */
- nullp++;
- if (nullp == smap_end)
- nullp = scr_map;
-
- while (ptr != nullp) {
- /* now send the field */
- thechar = *ptr++;
- if (thechar == IBMNULL) {
- if (emdp->nullsareblanks) {
- /* put out a blank */
- (*emdp->putchar)(0x40);
- }
- }
- else {
- /* translate character */
- (*emdp->putchar)(asctoebc[thechar]);
- }
- if (ptr == mapend)
- ptr = scr_map;
- }
- }
- ptr = nextattp;
- /* next attr */
- }
- /* end if MDT set .. */
- else
- ptr = look_attr(ptr, FWD);
- /* put us on attr */
- }
- while (ptr != endp);
- }
- }
- (*emdp->putchar)(0xff);
- (*emdp->putchar)(0xef);
- (*emdp->putflush)();
- /* telnet EOR */
- return();
- }
-
-
- /* this routine is called by cmd to process the 3270 command
- erase all unprotected and by prompt to process the erase input key */
-
- eau()
- {
- register unsigned char * curp;
- register unsigned char * eattp;
- register unsigned char * mapend = smap_end;
- unsigned char * endp; /* original curp position for end test */
- unsigned char * holdp; /* original curp position for set_mod */
-
- curp = scr_map + emdp->screensize - 1;
- /* start at end to wrap to top */
- endp = curp = next_unp(FWD);
- /* first position */
-
- if ((eattp = curp - 1) < scr_map)
- eattp += emdp->screensize;
- /* attr. itself */
-
- if (*eattp < ATTR && !(*eattp & PROT)) {
- /* if it really is an attr */
- current_attr = eattp;
- *eattp &= ~MDT;
- /* turn off MDT */
- holdp = curp;
- while (*curp >= ATTR) {
- /* null out the field */
- *curp++ = IBMNULL;
- if (curp == mapend) {
- set_mod(holdp, curp - holdp);
- holdp = curp = scr_map;
- }
- }
- set_mod(holdp, curp - holdp);
-
- /* repeat until we have reached our original field */
- while ((curp = next_unp(FWD)) != endp) {
- if ((eattp = curp - 1) < scr_map)
- eattp += emdp->screensize;
- *eattp &= ~MDT;
- for (holdp = curp; *curp >= ATTR; ) {
- /* null out the field */
- *curp++ = IBMNULL;
- if (curp == mapend) {
- set_mod(holdp, curp - holdp);
- holdp = curp = scr_map;
- }
- }
- set_mod(holdp, curp - holdp);
- }
- }
- else {
- /* no unprotected fields on screen */
- cursor_ptr = scr_map;
- newibmcursor();
- /* follow the book */
- current_attr = look_attr(scr_map, BACK);
- }
- }
-
-
- ibm_make()
- {
- short newsize = FALSE;
-
- if (emdp->scr_map != NULL)
- /* already has IBM structures allocated ... */
- return(0);
-
- switch (emdp->ibm_type) {
- case IBMMOD2: {
- emdp->linecount = COL_SIZE; /* 24 */
- emdp->linelength = ROW_SIZE; /* 80 */
- emdp->screensize = SCREEN_SIZE;
- break;
- }
- case IBMMOD3: {
- emdp->linecount = 32;
- emdp->linelength = 80;
- emdp->screensize = emdp->linecount * emdp->linelength;
- newsize = TRUE;
- break;
- }
- #ifdef SUPPORTMOD4
- /* emulator logic only handles <= 32 rows ... */
- case IBMMOD4: {
- emdp->linecount = 43;
- emdp->linelength = 80;
- emdp->screensize = emdp->linecount * emdp->linelength;
- newsize = TRUE;
- break;
- }
- #endif
- case IBMMOD5: {
- emdp->linecount = 27;
- emdp->linelength = 132;
- emdp->screensize = emdp->linecount * emdp->linelength;
- newsize = TRUE;
- break;
- }
- default: {
- emdp->linecount = COL_SIZE;
- emdp->linelength = ROW_SIZE;
- emdp->screensize = SCREEN_SIZE;
- break;
- }
- }
- emdp->lastcol = emdp->linelength - 1;
- emdp->lastrow = emdp->linecount - 1;
-
- if (!memtest((long) emdp->screensize, "to make 3270 emulator")) {
- return(-1);
- }
-
- emdp->scr_map = malloc(emdp->screensize); /* allocate the screen map */
- if (emdp->scr_map == NULL) {
- /* unlikely but conceivable */
- return(-1);
- }
-
- mem_clear(emdp->scr_map, emdp->screensize, (char) IBMNULL);
-
- if (emdp->color)
- emdp->realattr = DSPMOD;
- else
- emdp->realattr = DSPD;
-
- emdp->cmdstate = CMNORM;
- emdp->aid_key = AID_RESET;
-
- emdp->cursor_ptr = emdp->scr_map; /* current cursor position in screen map */
- emdp->smap_end = emdp->scr_map + emdp->screensize; /* end of map */
-
- emdp->ftsaveptr = &emdp->ftsavebuf[0]; /* TODO dynamic? ptr into buffer */
-
- setcontext(emdp); /* update globals */
-
- if (newsize)
- setscreensize(emdp->fontsize);
-
- newibmcursor();
-
- return(0);
- }
-
-
- /* free memory used by the ibm emulator */
-
- ibm_free(twp)
- struct winds * twp;
- {
- if (twp->scr_map != NULL)
- free(twp->scr_map);
- twp->scr_map = NULL;
-
- ftrecovermem(twp); /* free the file transfer memory */
- }
-
-
- ibm_init()
- {
- /* initialize the command map */
- commandmap[PT] = TRUE;
- commandmap[GE] = TRUE;
- commandmap[SBA] = TRUE;
- commandmap[EUA] = TRUE;
- commandmap[IC] = TRUE;
- commandmap[SF] = TRUE;
- commandmap[RA] = TRUE;
- commandmap[SA] = TRUE;
- commandmap[SFE] = TRUE;
- commandmap[MF] = TRUE;
- }
-
-
-
- ibm3270reset()
- {
- emdp->cmdstate = CMNORM;
- emdp->aid_key = AID_RESET;
- emdp->current_attr = NULL;
- emdp->cursor_ptr = emdp->scr_map;
- emdp->scr_org = scr_map;
-
- emdp->xpos = 0;
- emdp->ypos = 0;
-
- if (emdp->scr_map != NULL) {
- mem_clear(emdp->scr_map, emdp->screensize, (char) IBMNULL);
- }
-
- /* force an update */
- setcontext(emdp);
- newibmcursor();
- /* manually update the winds struct */
-
- if (emdp->emwindow)
- (*emdp->clear_scr)();
- }
-
-
- /*
- return the current attribute
- */
-
- pc_attr()
- {
- unsigned char temp;
-
- if (current_attr != NULL)
- temp = *current_attr;
- else
- temp = 0;
- return(temp);
- }
-
-
- /*
- look forward or back thru screen map for attribute byte;
- skips *ptr
- */
-
- unsigned char *look_attr (ptr, direction)
- register unsigned char *ptr;
- char direction;
- {
- register unsigned char * breakp;
- register unsigned char isattr = ATTR;
- unsigned char * tempp;
-
- tempp = ptr;
- if (direction == FWD) {
- ptr++;
- /* break on end of screen */
- breakp = smap_end;
- while (ptr < breakp) {
- if ( (*ptr++ < isattr) )
- return(ptr - 1);
- }
- /* now break on original ptr pos */
- breakp = tempp;
- ptr = scr_map;
- while (ptr <= breakp) {
- if ( (*ptr++ < isattr) )
- return(ptr - 1);
- }
- }
- else {
- /* as above */
- breakp = scr_map;
- while (--ptr >= breakp) {
- if ( (*ptr < isattr) )
- return(ptr);
- }
- breakp = tempp;
- ptr = smap_end;
- while (--ptr >= breakp) {
- if ( (*ptr < isattr) )
- return(ptr);
- }
- }
- return(NULL);
- /* no luck */
- }
-
-
- /*
- returns the attribute in force for this point
- */
-
- ibm_attr(ptr)
- register unsigned char *ptr;
- {
- register unsigned char * breakp;
- register unsigned char isattr = ATTR;
- unsigned char * tempp;
-
- ptr++; /* correct to adapt look_attr code: check *ptr TOO! */
- tempp = ptr;
-
- /* as above */
- breakp = scr_map;
- while (--ptr >= breakp) {
- if ( (*ptr < isattr) )
- return(*ptr);
- }
- breakp = tempp;
- ptr = smap_end;
- while (--ptr >= breakp) {
- if ( (*ptr < isattr) )
- return(*ptr);
- }
-
- return(0);
- /* no attribute in force... */
- }
-
-
- /*
- ***** find the byte following the next unprotected field
- */
-
- unsigned char *next_unp (direction)
- char direction;
- {
- register unsigned char *ptr;
- register unsigned char *nextp;
- register unsigned char *endp;
-
- ptr = cursor_ptr;
-
- if (direction == FWD) {
- if ((nextp = ptr + 1) == smap_end)
- nextp = scr_map;
- if (*ptr < ATTR && !(*ptr & PROT) && *nextp >= ATTR)
- return(nextp);
- }
- else
- if (--ptr < scr_map)
- ptr += emdp->screensize;
-
- if ((endp = ptr = look_attr(ptr, direction)) != NULL) {
- while (TRUE) {
- if ((*ptr & PROT) == FALSE) {
- if ((nextp = ptr + 1) == smap_end)
- nextp = scr_map;
- if (*nextp >= ATTR)
- /* it's data, and not just another attribute */
- return(nextp);
- }
- if ((ptr = look_attr(ptr, direction)) == endp)
- break;
- }
- }
- return(cursor_ptr);
- }
-
-
- /*
- ***** return pointer to byte following the next unprotected field,
- ***** if wrap occurs return scr_map
- */
-
- unsigned char *first_unp(start)
- char * start;
- {
- register unsigned char *ptr;
- register unsigned char *nextp;
- register unsigned char *startp;
-
- ptr = startp = start;
-
- if ((*ptr < ATTR) && !(*ptr & PROT)) {
- /* kevin -- test to verify first character not a field dropped */
- if ((nextp = ptr + 1) == smap_end)
- nextp = scr_map;
- return(nextp);
- }
-
- while ((ptr = look_attr(ptr, FWD)) != NULL) {
- if (ptr < startp)
- return(scr_map);
- /* if we've wrapped around, we set the pointer to buffer addr 0 */
-
- if ((*ptr & PROT) == FALSE) {
- if ((nextp = ptr + 1) == smap_end)
- nextp = scr_map;
- return(nextp);
-
- /* it's data, and not just another attribute
- Apparently we should not be testing this -- PT problem w/ XA
-
- if (*nextp >= ATTR)
- return(nextp);
- */
- }
- }
- return(scr_map);
- }
-
-
- /*
- **** generate 12 bit buffer address with appropriate IBM coding
- */
-
- int addr_12(convarg)
- int convarg;
- {
- register unsigned char achar;
- unsigned int x;
-
- achar = convarg / 64;
- achar |= 0x40;
- if ((achar & 0x0f) <= 9) {
- if ((achar & 0x30) == 0x30
- || (achar & 0x0f) >= 2
- || achar == 0x41
- || achar == 0x51
- )
- achar |= 0x80;
- }
- x = achar << 8;
- achar = convarg % 64;
- achar |= 0x40;
- if ((achar & 0x0f) <= 9) {
- if ((achar & 0x30) == 0x30
- || (achar & 0x0f) >= 2
- || achar == 0x41
- || achar == 0x51
- )
- achar |= 0x80;
- }
- x |= achar;
- return(x);
- }
-
- /*
- ***** clear an area of memory
- */
-
-
- mem_clear(clearptr, len, value)
- register char * clearptr;
- register int len;
- register char value;
- {
- register char * endptr;
-
- for (endptr = clearptr + len; clearptr < endptr; )
- *clearptr++ = value;
- }
-
-
- /* test a 3270 character stream to ascertain whether a DOWNLOAD is
- being requested
-
- check fmt:
- 0 1 2 3 4 5 6 7
- | SBA | ? | ? | SBA | ? | ? | 1B | 1B
-
- Presumably duplicate SBA's are a rare occurrence.
- */
-
- ft_check(ptr, length)
- register char *ptr;
- register int length;
- {
- /*
- if (length != 79)
- return(length);
- */
- if (*ptr != 0x11 && *(ptr + 3) != 0x11)
- return (length);
- if (*(ptr + 6) != 0x1b && *(ptr + 7) != 0x1b)
- return(length);
-
- emdp->event_reg |= TFTP_ON;
- msetsendm(FALSE); /* turn off send menu items */
-
- emdp->event_reg |= LINE_25;
- ft_header();
- (*emdp->putchar)(0xfd);
- (*emdp->putchar)(ftinit ( (int) *(ptr+8), 0)); /* version number */
- (*emdp->putchar)(0x00); /* zero indicates running tn */
- ft_trailer();
- return (0);
- }
-
-
-
- /* set modflg to reflect changed lines */
-
- set_mod(pmod, ccount)
- unsigned char * pmod; /* -> first position changed in map */
- register int ccount; /* # of characters changed */
- {
- register int line;
- register int count;
-
- if (modflg >= SCRALLMOD)
- /* the whole thing's been set already */
- return;
-
- line = (pmod - scr_map) / emdp->linelength; /* y pos */
- count = pmod - (scr_map + line * emdp->linelength); /* x pos */
-
- ccount += count;
- /* add xpos to ccount so end will come out right */
-
- for (count = 0; count < ccount; count += emdp->linelength) {
- modflg |= modmask[line];
- if (++line >= emdp->linecount)
- /* wrap around if necessary */
- line = 0;
- }
- }
-
-
-
-